package com.googlecode.ducktype;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxyFactory implements ProxyFactory {
   
    public static CGLibProxyFactory INSTANCE = new CGLibProxyFactory();
    
    public static ProxyFactory getInstance() { return INSTANCE; }
    
    protected CGLibProxyFactory() { }
    
    @SuppressWarnings("unchecked")
    public <T> T proxyFor(final Object objectToCoerce, final Class<T> type) {
        Enhancer enhancer = new Enhancer();
        if (type.isInterface()) {
            enhancer.setInterfaces(new Class<?>[] { type } );
        } else {
            enhancer.setSuperclass(type);
        }
        enhancer.setCallback(new MethodInterceptor() {
            
            public Object intercept(Object paramObject, Method method,
                    Object[] args, MethodProxy methodProxy)
                    throws Throwable {
                return DuckTyper.invokeProxyMethod(objectToCoerce, method, args);
                
            }        
        });
        return (T) enhancer.create();
    }

    
    
    

}
